package com.apestech.framework.xml.plugin.modul;

import com.apestech.framework.db.SqlSession;
import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.StringUtil;

import java.sql.SQLException;
import java.util.ArrayList;

/**
 * @author hup
 * @create 2019-01-26-17:30
 */
public class SysCondition extends StringUtil{

    public class Model {
        private String extend;
        private String control;
        private String bill;

        public Model(JSONObject map){
            extend=map.getString("extend");
            control=map.getString("control");
            bill=map.getString("bill");
        }

        public String getExtend() {
            return extend;
        }

        public String getControl() {
            return control;
        }

        public String getBill() {
            return bill;
        }
    }

    public class TableName {
        private String name;
        private String keyValue;

        public TableName(JSONObject map){
            name=map.getString("name");
            keyValue=map.getString("keyValue");
        }

        public String getName() {
            return name;
        }

        public String getKeyValue() {
            return keyValue;
        }
    }

    private SqlSession session;
    private Model model;
    private TableName tableName;
    private JSONObject dimension=new JSONObject();
    private JSONObject control=new JSONObject();
    private JSONObject fieldData=new JSONObject();
    private int row=3;
    private JSONObject rolefield=new JSONObject();

    public SysCondition(SqlSession session){
        this.session=session;
    }

    public void setModel(JSONObject map){
        model=new Model(map);
    }

    public void setTableName(JSONObject map){
        tableName=new TableName(map);
    }

    public SqlSession getSession() {
        return session;
    }

    public String getFieldName(String auxiliaryField){
        String sname=auxiliaryField;
        if(sname!=null && sname.indexOf(",")>0) sname=sname.split(",")[0];
        return sname;
    }

    public void addDimension(String id, JSONObject map) throws Exception {
        if(map==null) return;
        String type=map.getString("type");
        if(type!=null){
            addDimField(type, id, map);
        } else {
            addDimLookup(id, map);
        }
    }

    private void addDimField(String type, String id, JSONObject map) throws Exception {
        String name=map.getString("");
        if(name==null) name=map.getString("comment");
        if(name==null) name=id;
        JSONObject m=new JSONObject();
        m.put("id", id);
        m.put("type", type);
        m.put("notNull", "true");
        m.put("comment", name);
        m.put("field", id);
        m.put("defaultValue", map.getString("defaultValue"));
        m.put("foreignTab", map.getString("foreignTab"));
        m.put("foreignKey", map.getString("foreignKey"));
        dimension.put(id, m);
    }

    private void addDimLookup(String id, JSONObject map) throws Exception {
        String copyField=map.getString("copyField");
        String table=map.getString("table");
        String field=map.getString("field");
        String sql=map.getString("sql");
        if(table==null && copyField==null && sql==null) throw new Exception("table属性必填！");
        if(field==null && copyField==null) throw new Exception("field属性必填！");
        String name=map.getString("name");
        String auxiliaryField=map.getString("auxiliaryField");
        String auxiliaryName=map.getString("auxiliaryName");
        String qryCon=map.getString("qryCon");
        String sname=getFieldName(auxiliaryField);
        if(sql==null && copyField==null){
            String sauxiliaryField="A."+auxiliaryField.replace(",",",A.");
            sql=" SELECT A."+field+","+sauxiliaryField+" FROM "+table+" A WHERE 1=1 "+
                    " <if test=\"sysKey != null\"> AND (LOWER(A."+field+") LIKE #{sysKey} OR LOWER(A."+sname+") LIKE #{sysKey} OR LOWER(A.INITIALS) LIKE #{sysKey})</if>";
        }
        if(copyField!=null){  //table
            JSONObject m=new JSONObject();
            m.put("copyField", copyField);
            m.put("id", id);
            m.put("comment", name);
            dimension.put(id, m);
        } else {
            Table tab=null;
            try{
                if(table!=null) {
                    tab=session.getSqlTable("SELECT * FROM "+table+" WHERE 1 <> 1 ");
                }
                else tab=session.getSqlTable(sql+" AND 1 <> 1 ");
            } catch (Exception e){
                return;
            }
            if(tab!=null && tab.getTypeName(field)!=null){
                if(name==null) name=tab.getRemarks(field);
                if(name==null) name=id;
                JSONObject m=new JSONObject();
                m.put("id", id);
                String type=tab.getDbType(field);
                m.put("type", type);
                m.put("notNull", "true");
                m.put("comment", name);
                m.put("table", table);
                m.put("field", field);
                m.put("auxiliaryField", auxiliaryField);
                m.put("auxiliaryName", auxiliaryName);
                m.put("qryCon", qryCon);
                m.put("copyField", copyField);
                m.put("foreignTab", map.getString("foreignTab"));
                m.put("sql", sql);
                dimension.put(id, m);
            }
        }
    }

    public void addControl(String id, JSONObject map){
        if(map==null) return;
        if(map.get("")==null) map.put("id", id);
        control.put(id, map);
    }

    public JSONObject getDimension() {
        return dimension;
    }

    public JSONObject getDimensionField(String sid){
        if(dimension==null) return null;
        if(dimension.get(sid)==null) return null;
        JSONObject m=(JSONObject) dimension.get(sid);
        String copyField=m.getString("copyField");
        int pos=sid.indexOf(".");
        if(pos>=0 && copyField!=null) copyField=leftStr(sid, pos+1)+copyField;
        String sql=m.getString("sql");
        if(copyField!=null && sql==null){
            String name=m.getString("comment");
            if(dimension.get(copyField)!=null){
                m.putAll((JSONObject) dimension.get(copyField));
                m.put("id",sid);
                m.put("copyField", copyField);
                if(name!=null) m.put("comment",name);
            } else {
                copyField=m.getString("copyField");
                if(dimension.get(copyField)!=null){
                    m.putAll((JSONObject) dimension.get(copyField));
                    m.put("id",sid);
                    m.put("copyField", copyField);
                    if(name!=null) m.put("comment",name);
                }
            }
        }
        return m;
    }

    public JSONObject getControl() {
        return control;
    }

    public JSONObject getControlField(String sid){
        if(control==null) return null;
        if(control.get(sid)==null) return null;
        return (JSONObject) control.get(sid);
    }

    public Model getModel() {
        return model;
    }

    public JSONArray getFieldDataById(String id) throws Exception {
        JSONObject m=getDimensionField(id);
        if(m==null) return null;
        if(fieldData.get(id)==null){
            fieldData.put(id, session.getForJSON().query(m.getString("sql")+" AND ROWNUM<="+row));
        }
        if(fieldData.get(id)==null) return null;
        return (JSONArray) fieldData.get(id);
    }

    public Object getIdData(String id, int index) throws Exception {
        JSONObject m=getDimensionField(id);
        if(m==null) return null;
        JSONArray list=getFieldDataById(id);
        if(list==null) return null;
        if(index>=list.size()) return null;
        return list.get(index).get(m.getString("field"));
    }

    public Object getNameData(String id, int index) throws Exception {
        JSONObject m=getControlField(id);
        if(m==null) return null;
        JSONArray list=getFieldDataById(id);
        if(list==null) return null;
        if(index>=list.size()) return null;
        return list.get(index).get(m.getString("auxiliaryName"));
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getRow() {
        return row;
    }

    public TableName getTableName() {
        return tableName;
    }

    public JSONArray getConField(String db){
        JSONArray qlist=new JSONArray();
        ArrayList<String> klist=control.getKeylist();
        int len=klist.size();
        for(int i=0; i<len; i++){
            String k=klist.get(i);
            String theme=null;
            String field=k;
            int pos=k.indexOf(".");
            if(pos>=0){
                field=k.substring(pos+1, k.length());
                theme=k.substring(0, pos);
            }
            if(db==null || db.equals(theme)){
                JSONObject f= (JSONObject) control.get(k);
                JSONObject m=new JSONObject();
                m.put("ID", field);
                m.put("NAME", f.getString("comment"));
                m.put("TYPE", f.getString("type"));
                m.put("DEFAULT_VALUE", f.getString("defaultValue"));
                qlist.add(m);
            }
        }
        klist=dimension.getKeylist();
        len=klist.size();
        for(int i=0; i<len; i++){
            String k=klist.get(i);
            String theme=null;
            String field=k;
            int pos=k.indexOf(".");
            if(pos>=0){
                field=k.substring(pos+1, k.length());
                theme=k.substring(0, pos);
            }
            if(db==null || db.equals(theme)){
                JSONObject f= (JSONObject) dimension.get(k);
                JSONObject m=new JSONObject();
                m.put("ID", field);
                m.put("NAME", f.getString("comment"));
                m.put("TYPE", f.getString("type"));
                m.put("DEFAULT_VALUE", f.getString("defaultValue"));
                qlist.add(m);
            }
        }
        return qlist;
    }

    public void addRolefield(String id, JSONObject map){
        rolefield.put(id, map);
    }

    public JSONObject getRolefield(String id){
        if(id==null){
            return null;
        }
        if(id.indexOf(".")<0){
            id=session.getTheme()+"."+id;
        }
        return (JSONObject) rolefield.get(id);
    }
}
